<?

class Router {

	private $routes = array();
	private $prefixes = array();
	public static $instancia = null;
	private $prefix = null; // Prefix en uso
	private $enabledAuth = null;
	private $disabledAuth = null;

	function __construct () {
	}

	/**
	 * Devuelve una unica instancia de esta clase
	 * 
	 * @return object Instancia de esta clase
	 */
	public static function getInstance() {
		if (!self::$instancia instanceof self)
			self::$instancia = new self;
		return self::$instancia;
	}

	function addRoute ($regex, $destination) {
		if (!$destination['params'])
			$destination['params'] = array();
			
		$this->routes[] = array('regex' => $regex, 'destination' => $destination);
	}

	function addRoutes ($routes) {
		if (is_array($routes))
			foreach ($routes as $route)
				$this->addRoute($route['regex'], $route['destination']);
	}

	function getRoute ($url) {


		foreach ($this->routes as $route)
			if (preg_match($route['regex'], $url, $matches))
				return array_merge(
							array('method' => $route['destination']['controller']), 
							$route['destination'], 
							array('params' => $this->buildParams($route['destination']['params'], array_slice($matches, 1)))
						);

		return false;
	}

	function buildParams ($params=null, $matches=null) {

		if ($matches && !is_array($matches))
			$matches = array($matches);

		if ($params && is_array($params))
			foreach ($params as $k => $param)
				if (preg_match('/\$([0-9])/i', $param, $match))
					$params[$k] = (isset($matches[$match[1]-1]))? $matches[$match[1]-1] : null;
				else
					$params[$k] = $param;

		return (array)$params;
	}

	public function redirect ($url) {
		if ($this->prefix && !preg_match('/^'.preg_replace('/^\//', '', $this->prefix).'/i', preg_replace('/^\//', '', $url)))
			$url = preg_replace('/([\/]+)/', '/', $this->prefix.$url);

		header("Location: $url");
		exit;
	}

	public function addPrefix ($prefix, $name) {
		$this->prefixes[$prefix] = $name;
	}

	public function getPrefix (&$url) {

		$length = 0; 
		foreach ($this->prefixes as $prefix => $name) {
			if ((strpos($url, $prefix) === 0) && (strlen($name) > $length) && ($length = strlen($name)) )
				$this->prefix = $prefix;
		}
		if ($prefix)
			$url = str_replace($this->prefix, '', $url);

		return $this->prefixes[$this->prefix];
	}

	public function prefixName ($prefix=null) {
		$prefix = ($prefix)? $prefix : $this->prefix;
		return $this->prefixes[$prefix];
	}

	public function prefixPath ($name) {
		return array_search($name, $this->prefixes);
	}

	public function enableAuth ($prefix, $controllers) {
		$this->enabledAuth[$prefix] = $controllers;
	}

	public function disableAuth ($prefix, $controllers) {
		$this->disabledAuth[$prefix] = $controllers;
	}

	public function requiresAuth ($prefix, $controller, $method) {

/*
echo '<pre>disabledAuth: '.print_r($this->disabledAuth, true).'</pre>';
echo '<pre>enabledAuth: '.print_r($this->enabledAuth, true).'</pre>';
echo '<pre>Prefix: '.$prefix.'</pre>';
echo '<pre>Controller: '.$controller.'</pre>';
echo '<pre>Method: '.$method.'</pre>';
*/

		// Me fijo si esta desabilitada la autenticacion para este metodo o para todo el controlador
		if (($this->disabledAuth[$prefix] == '*') || in_array($method, $this->disabledAuth[$prefix][$controller]) || ($this->disabledAuth[$prefix][$controller] == '*') )
			return false;

//die('aa');
		// Me fijo si esta desabilitada la autenticacion para este metodo o para todo el controlador
		if (($this->enabledAuth[$prefix] == '*') || in_array($method, $this->enabledAuth[$prefix][$controller]) || ($this->enabledAuth[$prefix][$controller] == '*') )
			return true;

		return false;
	}

}

?>
